package com.chenyu.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.chenyu.client.AuthClients;
import com.chenyu.domain.Employee;
import com.chenyu.domain.LoginUser;
import com.chenyu.domain.Tenant;
import com.chenyu.domain.TenantMeal;
import com.chenyu.enums.SystemErrorCode;
import com.chenyu.mapper.TenantMapper;
import com.chenyu.service.IEmployeeService;
import com.chenyu.service.ITenantMealService;
import com.chenyu.service.ITenantService;
import com.chenyu.util.AjaxResult;
import com.chenyu.util.ChenyuAssert;
import com.chenyu.util.StrUtils;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.Date;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author chenyu
 * @since 2024-07-20
 */
@RequiredArgsConstructor
@Service
public class TenantServiceImpl extends ServiceImpl<TenantMapper, Tenant> implements ITenantService {

    private final IEmployeeService employeeService;

    private final ITenantMealService tenantMealService;

    private final AuthClients authClients;
    /**
     * 商家入驻
     *
     * @param tenant
     */
    @GlobalTransactional(rollbackFor = Exception.class)
    public void settledBusinesses(Tenant tenant) {
        /**
         * 1.对前端数据进行非空判断(controller层通过注解完成)
         * 2.租户重名验证
         * 3.自动审核 -- 住户店铺名  logo图片
         * 4.验证管理员两次密码是否一致和用户名是否重复
         * 5.生成商户数据 和 商户与套餐的中间表
         * 6.生成employee数据
         * 7.发起远程调用 调用auth服务  保存数据到t_login_user表
         */
        verifyInfo(tenant);

        Date date = new Date();
        //向数据库插入管理员信息,获取到主键后写入商户表中
        Employee admin = new Employee();
        BeanUtils.copyProperties(tenant.getAdmin(),admin);
        admin.setInputTime(date);
        String password = admin.getPassword();
        String salt = StrUtils.getComplexRandomString(32);
        //md5加密
        admin.setSalt(salt);
        String md5Password = DigestUtils.md5DigestAsHex((password + salt).getBytes());
        admin.setPassword(md5Password);
        employeeService.insert(admin);

        //向数据库插入店铺信息,获取到主键后 写入商户与套餐的中间表 与管理员信息表中
        tenant.setAdminId(admin.getId());
        tenant.setState(1);
        tenant.setRegisterTime(date);
        insert(tenant);

        //讲商户主键更新到管理员表中
        admin.setTenantId(tenant.getId());

        //创建商户与套餐的中间表
        TenantMeal tenantMeal = new TenantMeal();
        tenantMeal.setTenantId(tenant.getId());
        tenantMeal.setMealId(tenant.getMealId());
        tenantMeal.setState(1);
        tenantMeal.setExpireDate(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 30));
        tenantMealService.insert(tenantMeal);

        //发起远程调用 调用auth服务  保存数据到t_login_user表，获取到主键存储在管理员表中
        LoginUser loginUser = new LoginUser();
        BeanUtils.copyProperties(admin,loginUser);
        loginUser.setType(1);
        loginUser.setId(null);
        AjaxResult result = authClients.addOrUpdate(loginUser);

        //将t_login_user的主键更新到管理员表中
        admin.setLoginId( Long.valueOf(result.getData().toString()) );
        employeeService.updateById(admin);
    }

    /**
     * 用于验证Tenant(租户)的信息
     *
     * @param tenant
     */
    private void verifyInfo(Tenant tenant) {
        //2.租户重名验证
        EntityWrapper<Tenant> tenantWrapper = new EntityWrapper<>();
        tenantWrapper.eq("company_name", tenant.getCompanyName());
        Tenant dbTenant = selectOne(tenantWrapper);
        ChenyuAssert.isNull(dbTenant, SystemErrorCode.RESPONSE_CODE_400002);
        //TODO 3.自动审核 -- 住户店铺名  logo图片

        //4.验证管理员两次密码是否一致和用户名是否重复
        //4.1.验证管理员两次密码是否一致
        ChenyuAssert.isEq(
                tenant.getAdmin().getPassword(),
                tenant.getAdmin().getConfirmPassword(),
                SystemErrorCode.RESPONSE_CODE_400001
        );
        //4.2.验证管理员用户名是否重复
        EntityWrapper<Employee> employeeWrapper = new EntityWrapper<>();
        employeeWrapper.eq("username", tenant.getAdmin().getUsername());
        Employee dbEmployee = employeeService.selectOne(employeeWrapper);
        ChenyuAssert.isNull(dbEmployee, SystemErrorCode.RESPONSE_CODE_400003);
    }
}
